<?php

namespace App\Services;

use Illuminate\Contracts\Pagination\LengthAwarePaginator;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Support\Arr;

class BaseService
{
    protected Builder|BelongsToMany $query;

    /**
     * 参数数组
     * @var array
     */
    public array $params = [];

    /**
     * 设置全部参数
     * @param array $params
     * @return self
     */
    public function setParams(array $params)
    {
        //如果存在成员变量,则赋值
        foreach ($params as $k => $v) {
            $this->params[$k] = $v;
        }
        return $this;
    }

    /**
     * 设置单个参数
     * @param $key
     * @param $value
     * @return self
     */
    public function setParam($key, $value)
    {
        $this->params[$key] = $value;
        return $this;
    }

    /**
     * 获取所有参数
     * @return array
     */
    public function getParams(): array
    {
        return $this->params;
    }

    /**
     * 删除指定参数
     * @param $key
     * @param $default
     * @return array|\ArrayAccess|mixed
     */
    public function popParam($key, $default = null)
    {
        $param = $this->getParam($key, $default);
        unset($this->params[$key]);
        return $param;
    }

    /**
     * 获取单个参数
     * @param $key
     * @param null $default
     * @return array|\ArrayAccess|mixed
     */
    public function getParam($key, $default = null): mixed
    {
        return Arr::get($this->params, $key, $default);
    }

    /**
     * 自实现查询过滤器
     * @return void
     */
    protected function filter(): void
    {
    }

    /**
     * 指定查询实例模型
     * @param Builder $query
     */
    protected function setQuery(Builder $query): void
    {
        $this->query = $query;
    }

    /**
     * 默认分页偏移量
     * @return int
     */
    protected function getPerPage(): int
    {
        return (int)request('limit', 15);
    }

    public function setDefaultSort($type, $sort = 'desc'): void
    {
        $this->setParam('default_sort_type', $type);
        $this->setParam('sort', $this->getParam('sort', $sort));
    }

    /**
     * 分页查询
     * @param string[] $columns
     * @param string $pageName
     * @param null $page
     * @return LengthAwarePaginator
     */
    protected function paginate(array $columns = ['*'], string $pageName = 'page', $page = null): LengthAwarePaginator
    {
        $this->filter();
        $this->sorts();
        $this->sortByRaws();
        return $this->query->paginate($this->getPerPage(), $columns, $pageName, $page);
    }

    /**
     * 默认id排序
     * @return Builder
     */
    protected function sorts(): Builder
    {
        if ($sortType = $this->getParam('sort_type', $this->getParam('default_sort_type', 'id'))) {
            $this->query->orderBy($sortType, $this->getParam('sort', 'desc'));
        }

        return $this->query;
    }

    //多字段排序
    protected function sortByRaws(): Builder
    {
        if ($sortType = $this->getParam('sort_by_raws')) {
            $this->query->reorder()->orderByRaw($sortType);
        }

        return $this->query;
    }

    /**
     * 集合查询
     * @return Collection
     */
    protected function get(): Collection
    {
        $this->filter();
        $this->sorts();
        $this->sortByRaws();
        return $this->query->get();
    }
}
